<?

class SmileLaughDetector {
	
	public function __construct() {}

	// This function finds a large set of smiles, and returns the number of positive and negative smiles, with the original text without them.
	public function findSmiles($text) {
		//detects positive smiles like: :) , :))),  :D , :DDD , :* , :** , xd Xd xD XD, =) =))) :-))) :-D :-*
		$pattern = "/(((\:|\=)\-?(\)|d|\*)+)|(((x)(d+))|(xd))|(\<3))/i";
		
		$result = $this -> removeSmiles($text, $pattern);
		
		$text = $result[0];
		$num_of_pos_smile = $result[1]; 
		
		//detects negative smiles like: :( , :((((,  :O , :OOOO , :S , :SSS , =( =O, =S, =OOO
		$pattern = "/(((\:|\=)\-?(\(|o|s)+)|(\:\'\())/i";
		
		$result = $this -> removeSmiles($text, $pattern);
		
		$text = $result[0];
		$num_of_neg_smile = $result[1]; 
		
		//detects neutral smiles, like: :P, :PP, ://, :/, :\ :\\, =/, =\, =P
		$pattern = "/(\:|\=)\-?(\\|p|\/)+/i";
		
		$result = $this -> removeSmiles($text, $pattern);
		
		$text = $result[0];
		
		return array($text, $num_of_pos_smile, $num_of_neg_smile); 
	}
	
	// Function in which, given a pattern to search, it returns the number of occurrences and the text without the searched string
	private function removeSmiles($text, $pattern) {
	
		$smiles_count = preg_match_all($pattern, $text, $matches);
		
		usort($matches[0], array($this, "cmp"));
		
		$ordered = array();
		foreach ($matches[0] as $key)
			array_push($ordered, $key);
		
		$text = str_replace($ordered, '', $text);
		
		return array($text, $smiles_count);
	}
	
	// Utility function for compare objects
	public function cmp($a, $b) {
		if (strlen($a) == strlen($b)) {
			return 0;
		}
		return (strlen($a) < strlen($b)) ? 1 : -1;
	}
	
	
	// Function that returns true if the given word is a laugh, like "ahahhahhhhahh" or "hihi" or "eheh", false otherwise
	public function isLaughing($word) {
		// the lenght of a laugh has to be at least 3 (to avoid different expressions like 'a', 'ah', 'oh', etc) 
		if (strlen($word) < 3)
			return false;
		
		$vowels = array('a' => 1, 'e' => 1, 'i' => 1, 'o' => 1, 'u' => 1, 'g' => 1);
		// for future improvements
		$consonant = array('h' => 1);
		
		// find the first vowel
		for ($i = 0; $i < strlen($word); $i++)
			if ($vowels[$word[$i]]) {
				$vocale[$word[$i]] = 1;
				if ($word[$i] == 'a' || $word[$i] == 'u') {
					$vocale['a'] = 1;
					$vocale['u'] = 1;
				}
				break;
			}
		
		$laugh = true;
		
		// check that in the word there are only alternate occurrences of a consonant and a vowel
		for ($i = 0; $i < strlen($word); $i++)
			if (!($word[$i] == 'h' ||  $vocale[$word[$i]]))
				$laugh = false;
		
		return $laugh;
	}
}
?>